package com.clpms.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.clpms.bean.enumBean.ErrorCodeEnum;
import com.clpms.bean.req.*;
import com.clpms.bean.resp.*;
import com.clpms.dao.mapper.*;
import com.clpms.dao.pojo.LearnRecord;
import com.clpms.dao.pojo.School;
import com.clpms.dao.pojo.Teacher;
import com.clpms.service.TeacherService;
import com.clpms.utils.CommonException;
import com.clpms.utils.CurrentUser;
import com.clpms.utils.UserUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author caixinyong
 * @date 2023/5/5 5:13 PM
 */

@Service
@Slf4j
public class TeacherServiceImpl implements TeacherService {

    public static final String COOKIE_NAME = "userInfo";
    private static final Integer EXPIRE_TIME = 60 * 60 * 24 * 7;

    private static final String INIT_PASSWORD = "123456";

    @Resource
    private TeacherDao teacherDao;

    @Resource
    private SchoolDao schoolDao;

    @Resource
    private CourseDao courseDao;

    @Resource
    private WorkDao workDao;

    @Resource
    private LearnRecordDao learnRecordDao;

    /**
     * 登录
     *
     * @param req
     * @param response
     * @return
     */
    @Override
    public LoginResp login(LoginReq req, HttpServletResponse response) {

        Teacher teacher = teacherDao.selectByJobNumberAndPassword(req.getJobNumber(), req.getPassword(),
                req.getSchoolId());
        if (Objects.isNull(teacher)) {
            return LoginResp.builder().successFlag(Boolean.FALSE).build();
        }

        Long schoolId = teacher.getSchoolId();
        School school = schoolDao.selectById(schoolId);
        if (Objects.isNull(school)) {
            return LoginResp.builder().successFlag(Boolean.FALSE).build();
        }

        LoginResp loginResp =
                LoginResp.builder()
                        .successFlag(Boolean.TRUE)
                        .schoolId(schoolId)
                        .schoolName(school.getName())
                        .teacherId(teacher.getId())
                        .teacherName(teacher.getName())
                        .jobNumber(teacher.getJobNumber())
                        .roleType(teacher.getRoleType())
                        .build();
        byte[] cookieValue =
                Base64.getEncoder().encode(JSONObject.toJSONString(loginResp).getBytes(StandardCharsets.UTF_8));
        Cookie cookie = new Cookie(COOKIE_NAME, new String(cookieValue, StandardCharsets.UTF_8));
        cookie.setMaxAge(EXPIRE_TIME);
        cookie.setPath("/");
        response.addCookie(cookie);
        return loginResp;
    }

    @Override
    public PageInfo<QueryTeacherResp> queryTeacher(QueryTeacherReq req) {
        CurrentUser currentUser = UserUtils.get();
        Long schoolId = currentUser.getSchoolId();
        String keyWord = Optional.ofNullable(req.getKeyWord()).orElse(StringUtils.EMPTY).trim();
        PageHelper.startPage(req.getPageNum(), req.getPageSize());
        List<Teacher> teacherList = teacherDao.selectByKeyWord(keyWord, req.getRoleType(), schoolId);

        // 使用 Stream 将 Teacher 对象转换为 QueryTeacherResp 对象
        List<QueryTeacherResp> respList =
                teacherList.stream().map(this::convertToQueryTeacherResp).collect(Collectors.toList());
        PageInfo<QueryTeacherResp> pageInfo = new PageInfo<>(respList);
        return pageInfo;
    }

    /**
     * 删除教师
     *
     * @param req
     * @return
     */
    @Override
    public DeleteTeacherResp deleteTeacher(DeleteTeacherReq req) {
        CurrentUser currentUser = UserUtils.get();
        Long teacherId = req.getTeacherId();
        teacherDao.deleteById(teacherId, currentUser.getSchoolId());
        return DeleteTeacherResp.builder().successFlag(Boolean.TRUE).build();
    }

    @Override
    public TeacherAddResp updateOrAdd(TeacherAddReq req) {
        CurrentUser currentUser = UserUtils.get();

        //新增
        if (Objects.isNull(req.getId())) {
            Teacher teacher = teacherDao.selectByJobNumber(req.getJobNumber(), currentUser.getSchoolId());
            if (Objects.nonNull(teacher)) {
                throw new CommonException(ErrorCodeEnum.PARAM_ERROR.getCode(),
                        String.format("添加失败，工号【%s】是【%s】的工号", req.getJobNumber(), teacher.getName()));
            }
            Teacher add = Teacher.builder()
                    .name(req.getName())
                    .jobNumber(req.getJobNumber())
                    .schoolId(currentUser.getSchoolId())
                    .password(INIT_PASSWORD)
                    .roleType(req.getRoleType())
                    .build();
            teacherDao.insertList(Collections.singletonList(add));
            return TeacherAddResp.builder().successFlag(Boolean.TRUE).message("添加成功").build();
        }

        //修改
        //1.判断教师是否存在
        Teacher teacher = teacherDao.selectById(req.getId(), currentUser.getSchoolId());
        if (Objects.isNull(teacher)) {
            throw new CommonException (ErrorCodeEnum.PARAM_ERROR.getCode(),
                    String.format("修改失败，教师【%s】不存在", req.getId()));
        }
        //2.判断工号是否存在
        Teacher teacherByJobNumber = teacherDao.selectByJobNumber(req.getJobNumber(), currentUser.getSchoolId());
        if (Objects.nonNull(teacherByJobNumber) && !teacherByJobNumber.getId().equals(req.getId())) {
            throw new CommonException(ErrorCodeEnum.PARAM_ERROR.getCode(),
                    String.format("修改失败，工号【%s】是【%s】的工号", req.getJobNumber(), teacherByJobNumber.getName()));
        }

        //3.修改
        Teacher update = Teacher.builder()
                .id(req.getId())
                .name(req.getName())
                .jobNumber(req.getJobNumber())
                .schoolId(currentUser.getSchoolId())
                .roleType(req.getRoleType())
                .build();
        teacherDao.updateById(update);
        return TeacherAddResp.builder().successFlag(Boolean.TRUE).message("修改成功").build();
    }

    /**
     * 查询当前教师的总览信息
     *
     * @return
     */
    @Override
    public OverviewResp overview() {
        CurrentUser currentUser = UserUtils.get();
        Long totalCourseNumber =
                courseDao.selectCountByTeacherId(currentUser.getTeacherId(), currentUser.getSchoolId());
        Long totalWorkNumber =
                workDao.selectCountByTeacherId(currentUser.getTeacherId(), currentUser.getSchoolId());
        Long totalLearnRecordNumber =
                learnRecordDao.selectCountByTeacherId(currentUser.getTeacherId(), currentUser.getSchoolId());
        List<LearnRecord> learnRecords =
                learnRecordDao.selectAllByTeacherId(currentUser.getTeacherId(), currentUser.getSchoolId());

        List<LearnRecordForWorkResp> allLearnRecord =
                learnRecords.stream().map(learnRecord ->
                                LearnRecordForWorkResp.builder()
                                        .id(learnRecord.getId())
                                        .remark(learnRecord.getRemark())
                                        .score(learnRecord.getScore())
                                        .completionTime(learnRecord.getCompletionTime())
                                        .easyType(learnRecord.getEasyType())
                                        .progress(learnRecord.getProgress())
                                        .workId(learnRecord.getWorkId())
                                        .build())
                        .collect(Collectors.toList());

        return OverviewResp.builder()
                .totalCourseNumber(totalCourseNumber)
                .totalWorkNumber(totalWorkNumber)
                .totalLearnRecordNumber(totalLearnRecordNumber)
                .allLearnRecord(allLearnRecord)
                .build();
    }

    @Override
    public Boolean resetPassword(ResetPasswordReq req) {
        CurrentUser currentUser = UserUtils.get();
        teacherDao.updatePasswordById(req.getTeacherId(), currentUser.getSchoolId(), INIT_PASSWORD);
        return Boolean.TRUE;
    }

    @Override
    public Boolean changePassword(ChangePasswordReq req) {
        if (!Objects.equals(req.getNewPassword(), req.getNewPasswordAgain())) {
            throw new CommonException(ErrorCodeEnum.PARAM_ERROR.getCode(), "两次密码不一致");
        }
        if (req.getNewPassword().length() < 6 || req.getNewPassword().length() > 12) {
            throw new CommonException(ErrorCodeEnum.PARAM_ERROR.getCode(), "密码长度应为6-12位");
        }

        CurrentUser currentUser = UserUtils.get();
        Teacher teacher = teacherDao.selectById(currentUser.getTeacherId(), currentUser.getSchoolId());
        if (!Objects.equals(teacher.getPassword(), req.getOldPassword())) {
            throw new CommonException(ErrorCodeEnum.PARAM_ERROR.getCode(), "原密码错误");
        }
        teacherDao.updatePasswordById(currentUser.getTeacherId(), currentUser.getSchoolId(), req.getNewPassword());
        return Boolean.TRUE;
    }

    private QueryTeacherResp convertToQueryTeacherResp(Teacher teacher) {
        return QueryTeacherResp.builder()
                .id(teacher.getId())
                .name(teacher.getName())
                .jobNumber(teacher.getJobNumber())
                .roleType(teacher.getRoleType())
                .build();
    }

}
